package org.song.videoplayer.media;

import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.media.audio.AudioManager;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by song on 2017/2/10.
 * Contact github.com/tohodog
 * 安卓系统硬解
 */

public class HarmonyMedia extends BaseMedia implements Player.IPlayerCallback {

    public Player mediaPlayer;

    public HarmonyMedia(IMediaCallback iMediaCallback) {
        super(iMediaCallback);
    }

    /////////////以下MediaPlayer控制/////////////
    @Override
    public boolean doPrepar(Context context, String url, Map<String, String> headers, Object... objects) {
        try {
            release();
            mediaPlayer = new Player(context);
            mediaPlayer.setAudioStreamType(AudioManager.AudioVolumeType.STREAM_MUSIC.ordinal());
            if (url.startsWith("content") || url.startsWith("hos.resource")) {
                mediaPlayer.setSource(new Source(url, headers));
            } else if (url.startsWith("file")) {
                mediaPlayer.setSource(new Source(url.replace("file:/", "")));
            } else {
                try {
                    Class<Player> clazz = Player.class;
                    Method method = clazz.getDeclaredMethod("setSource", Source.class);
                    method.invoke(mediaPlayer, new Source(url, headers));//反射
                } catch (Exception e) {
                    e.printStackTrace();
                    mediaPlayer.setSource(new Source(url));
                }
            }
            mediaPlayer.enableSingleLooping(false);
            mediaPlayer.setPlayerCallback(this);
            new EventHandler(EventRunner.create()).postTask(() -> mediaPlayer.prepare());
            //mediaPlayer.setDisplay();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            onError(MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNKNOWN);
            return false;
        }
    }

    @Override
    public void setSurface(Surface surface) {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.setVideoSurface(surface);
            }
            this.surface = surface;
        } catch (Exception e) {
            e.printStackTrace();
            onError(MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNKNOWN);
        }
    }

    @Override
    public void setDisplay(SurfaceOps surfaceHolder) {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.setSurfaceOps(surfaceHolder);
            }
            if (surfaceHolder != null)
                this.surface = surfaceHolder.getSurface();
        } catch (Exception e) {
            e.printStackTrace();
            onError(MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNKNOWN);
        }
    }

    @Override
    public void doPlay() {
        if (!isPrepar)
            return;
        mediaPlayer.play();
    }

    @Override
    public void doPause() {
        if (!isPrepar)
            return;
        mediaPlayer.pause();
    }

    @Override
    public void seekTo(int duration) {
        if (!isPrepar)
            return;
        mediaPlayer.rewindTo(duration * 1000L);//ohos的单位是微秒
    }

    @Override
    public int getCurrentPosition() {
        if (!isPrepar)
            return 0;
        try {
            return mediaPlayer.getCurrentTime();
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public int getDuration() {
        if (!isPrepar)
            return 0;
        try {
            return mediaPlayer.getDuration();
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public int getVideoHeight() {
        if (!isPrepar)
            return 0;
        return mediaPlayer.getVideoHeight();
    }

    @Override
    public int getVideowidth() {
        if (!isPrepar)
            return 0;
        return mediaPlayer.getVideoWidth();
    }

    @Override
    public boolean isPlaying() {
        if (!isPrepar)
            return false;
        return mediaPlayer.isNowPlaying();
    }

    @Override
    public boolean setVolume(float volume) {
        if (isPrepar)
            mediaPlayer.setVolume(volume);
        return true;
    }

    @Override
    public boolean setSpeed(float rate) {
        return false;
    }

    @Override
    public void release() {
        isPrepar = false;
        this.surface = null;
        if (mediaPlayer != null)
            mediaPlayer.release();
        mediaPlayer = null;
    }

    /////////////以下MediaPlayer回调//////////////

    @Override
    public void onPrepared() {
        isPrepar = true;
        iMediaCallback.onPrepared(this);
        System.out.println("===onPrepared===>");
    }

    @Override
    public void onMessage(int what, int extra) {
        iMediaCallback.onInfo(this, what, extra);
        System.out.println("===onMessage===>");
    }

    @Override
    public void onError(int what, int extra) {
        iMediaCallback.onError(this, what, extra);
        isPrepar = false;
        System.out.println("===onError===>");
    }

    @Override
    public void onResolutionChanged(int width, int height) {
        iMediaCallback.onVideoSizeChanged(HarmonyMedia.this, width, height);
    }

    @Override
    public void onPlayBackComplete() {
        iMediaCallback.onCompletion(this);
        System.out.println("===onPlayBackComplete===>");
    }

    @Override
    public void onRewindToComplete() {
        iMediaCallback.onSeekComplete(this);
        System.out.println("===onRewindToComplete===>" + getCurrentPosition());
    }

    @Override
    public void onBufferingChange(int percent) {
        iMediaCallback.onBufferingUpdate(this, percent / 100.0f);
        System.out.println("===onBufferingChange===>" + percent);
    }

    @Override
    public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
        System.out.println("===onNewTimedMetaData===>");
    }

    @Override
    public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
        System.out.println("===onMediaTimeIncontinuity===>");
    }
}
